package com.wiloon.java8x.portscan;

import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestScanHost {

    public static void main(String[] args) {

        // scanPortForIp("127.0.0.1");

    }

    public static void scanPortForIp(String ip) {
        ExecuteServices service = ExecuteServices.getInstance();
        service.startup(255);
        service.exeuteTask(new Thread1(ip));
    }

    public static void ipScanner(String ip) {
        ExecuteServices service = ExecuteServices.getInstance();
        service.startup(5);
        for (int i = 80; i < 100; i++) {
            PortScanner ps = new PortScanner(ip, i);
            service.exeuteTask(ps);

        }
    }

    public static void scanLan() {
        // 定义IP 区段
        String ip1 = ""; // 范围 1
        String ip2 = ""; // 范围 2

        try {
            InetAddress localAddress = InetAddress.getLocalHost();
            String hostAddress = localAddress.getHostAddress(); // 获取本机IP地址
            int dotPos = hostAddress.lastIndexOf(".");
            ip1 = hostAddress.substring(0, dotPos + 1); // 设置IP区头前段
            ip2 = hostAddress.substring(0, dotPos + 1); // 设置IP区头后段

        } catch (UnknownHostException e1) {
            e1.printStackTrace();
        }
        // new testOpenPortThread("192.168.1.106").scanPort();

        ExecuteServices service = ExecuteServices.getInstance();
        service.startup(255); // 设置默认线程池大小
        try {
            for (int i = 1; i < 255; i++) {
                final String ipaddress = ip1 + i;
                scanPortForIp(ipaddress);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class ExecuteServices {
    private static ExecutorService service = null;
    private static Lock write_lock = new ReentrantLock();

    private static int threadPool = 255; // 线程池大小

    public void startup(int threadPool) {
        this.threadPool = threadPool;
        service = Executors.newFixedThreadPool(threadPool); // 创建线程池
    }

    private static ExecuteServices instance = new ExecuteServices();

    public static ExecuteServices getInstance() {
        if (instance == null) {
            instance = new ExecuteServices();
        }
        return instance;
    }

    public static void exeuteTask(Runnable task) {
        service.execute(task);
    }

}

class Thread1 implements Runnable {
    private String hostaddress;

    public Thread1(String hostaddress) {
        this.hostaddress = hostaddress;
    }

    @Override
    public void run() {
        try {
            InetAddress address = InetAddress.getByName(hostaddress);
            // if (address.isReachable(3000)) // 测试3秒内是否能够到达此地址
            if (true) // 测试3秒内是否能够到达此地址
            {
                System.out.println(address.getHostAddress() + ":on line");
                new Thread(new TestOpenPort(hostaddress)).start(); // 扫描开放端口
            } else {
                System.out.println(address.getHostAddress()
                        + ":connection time out");
            }
        } catch (Exception e) {
        }
    }
}

class TestOpenPort implements Runnable {
    private String hostaddress;

    TestOpenPort(String hostaddress) {
        this.hostaddress = hostaddress;
    }

    public void run() {
        ExecuteServices service = ExecuteServices.getInstance();
        service.startup(5);
        for (int i = 80; i < 100; i++) {
            PortScanner ps = new PortScanner(hostaddress, i);
            service.exeuteTask(ps);

        }
    }

}

class PortScanner implements Runnable {
    private String ip;
    private int port;

    public PortScanner(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }

    @Override
    public void run() {

        Socket socket;
        try {
            socket = new Socket(ip, port);
            if (socket.isConnected()) {
                System.out.println("");
                System.out.println(ip + ":" + port + " open");
            }
        } catch (Exception e) {
            System.out.print("[" + port + "]");
        }

    }
}